
package numberporting.server;

import numberporting.service.SMSService;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import javax.xml.ws.Endpoint;
import numberporting.bean.*;
import numberporting.service.CustomerManagementService;
import numberporting.service.CustomerServiceWrapper;
import numberporting.service.MailService;
import numberporting.service.NumberPortingService;
import numberporting.service.PortingQueue;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;

public class Server {

    private CustomerStore customerStore;
    private PortingQueue portingQueue;
    private boolean security;

    protected Server(boolean security) throws Exception {
        this.security = security;
        this.customerStore = new CustomerStore();
        this.portingQueue = new PortingQueue();
        customerStore.addCustomer(new Customer("1","Christian"));
        customerStore.addCustomer(new Customer("2","Thomas"));
        customerStore.addCustomer(new Customer("3","Stephan"));
        customerStore.addCustomer(new Customer("4","Illegal User"));
        customerStore.saveToFile();
    }

    public static void main(String args[]) throws Exception {
        
        boolean addSecurity = true;
        if(args.length > 0){
            if(args[0].equals("nosec")){
                addSecurity = false;
            }
        }

        int minutesListening = 15;
        Server server = new Server(addSecurity);
        server.startNumberPortingService("http://localhost:8083/numberportingservice");
        server.startSMSService("http://localhost:8088/smsservice");
        server.startMailService("http://localhost:8089/mailservice");
        server.startCustomerManagementService("http://localhost:8084/customers");
        server.startCustomerWrapperService("http://localhost:8012/customers");
        System.out.println("Server ready... will listen for "+minutesListening+" minutes");
        if(!addSecurity)
        {
            System.out.println("Server started without security!");
        }
        //starts PortingProcedure
        server.startPortingProcedure();
        
        Thread.sleep(minutesListening * 60 * 1000);
        System.out.println("Server exiting");
        System.exit(0);
    }


    public void addWssInterceptors(org.apache.cxf.endpoint.Endpoint cxfEndpoint) {
        Map<String,Object> inProps= new HashMap<String, Object>();
        inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
        inProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
        inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServerPasswordCallback.class.getName());

        WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps); 
        cxfEndpoint.getInInterceptors().add(wssIn);
    }
    
    private void startCustomerManagementService(String address) {
        System.out.println("Starting CustomerManagementService on "+address);
        System.out.println("---------------------------------");
        JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
        CustomerManagementService cms = new CustomerManagementService(this.customerStore);
        sf.setServiceBeans(cms);
        sf.setAddress(address);
        sf.create();
    }

    private void startCustomerWrapperService(String address){
        String wrappedServiceAddress = "http://localhost:8084/customers";
        System.out.println("Starting CustomerServiceWrapper on "+address);
        System.out.println("---------------------------------");
        CustomerServiceWrapper service = new CustomerServiceWrapper(wrappedServiceAddress);
        EndpointImpl jaxWsEndpoint = (EndpointImpl) Endpoint.publish(address, service);
        org.apache.cxf.endpoint.Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
    }
    
    private void startNumberPortingService(String address)
    {
        System.out.println("Starting NumberPortingServic on" +address);
        System.out.println("---------------------------------");
        NumberPortingService nps = new NumberPortingService(this.customerStore,this.portingQueue);
        EndpointImpl jaxWsEndpoint = (EndpointImpl) Endpoint.publish(address, nps);
        org.apache.cxf.endpoint.Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
        if(this.security){
            addWssInterceptors(cxfEndpoint);
        }
    }
    
    private void startPortingProcedure()
    {
        Timer timer = new Timer();
        timer.schedule(new PortingProcedure(this.portingQueue), 1000,30000);
    }

    private void startMailService(String address) {
        System.out.println("Starting MailService on "+address);
        System.out.println("---------------------------------");
        MailService service = new MailService(this.customerStore);
        EndpointImpl jaxWsEndpoint = (EndpointImpl) Endpoint.publish(address, service);
        org.apache.cxf.endpoint.Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
        if(this.security){
            this.addWssInterceptors(cxfEndpoint);
        }
    }

    private void startSMSService(String address) {
        System.out.println("Starting SMSService on "+address);
        System.out.println("---------------------------------");
        SMSService service = new SMSService(this.customerStore);
        EndpointImpl jaxWsEndpoint = (EndpointImpl)Endpoint.publish(address, service);
        org.apache.cxf.endpoint.Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
        if(this.security){
            this.addWssInterceptors(cxfEndpoint);
        }
    }
}
